package com.movie.ui;

import com.movie.model.Movie;
import com.movie.model.Screening;
import com.movie.service.AdminService;
import com.movie.util.DataUtil;
import com.movie.util.ApiDocUtil;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.UUID;

public class AdminUI extends JFrame {

    private AdminService adminService;
    private JTabbedPane tabbedPane;
    private JTable movieTable;
    private JTable screeningTable;
    private DefaultTableModel movieTableModel;
    private DefaultTableModel screeningTableModel;

    public AdminUI(AdminService adminService, DataUtil dataUtil) {
        this.adminService = adminService;
        setTitle("管理员系统");
        setSize(800, 600);
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        // 创建选项卡面板
        tabbedPane = new JTabbedPane();

        createMovieTab();
        createScreeningTab();

        // 创建退出按钮
        JButton exitButton = new JButton("Exit");
        exitButton.addActionListener(e -> {
            dispose(); // 关闭当前窗口
            System.exit(0); // 退出整个应用程序
        });

         //创建 API 文档按钮
        JButton apiDocButton = new JButton("API 文档");
        apiDocButton.addActionListener(e -> ApiDocUtil.showAdminApiDocument(this));

        // 将按钮放入面板
        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        buttonPanel.add(apiDocButton);
        buttonPanel.add(exitButton);

        // 将选项卡面板和按钮面板都加入窗口
        add(tabbedPane, BorderLayout.CENTER);
        add(buttonPanel, BorderLayout.SOUTH);

        setVisible(true);
    }


    private void createMovieTab(){
        JPanel moviePanel = new JPanel(new BorderLayout());
        movieTableModel = new DefaultTableModel(new Object[]{"ID", "Title", "Director", "Genre", "Duration"}, 0);
        movieTable = new JTable(movieTableModel);
        JScrollPane movieScrollPane = new JScrollPane(movieTable);
        moviePanel.add(movieScrollPane, BorderLayout.CENTER);

        JPanel movieButtonPanel = new JPanel();
        JButton addMovieButton = new JButton("Add Movie");
        addMovieButton.addActionListener(e -> showAddMovieDialog());

        JButton editMovieButton = new JButton("Edit Movie");
        editMovieButton.addActionListener(e -> showEditMovieDialog());

        JButton deleteMovieButton = new JButton("Delete Movie");
        deleteMovieButton.addActionListener(e -> deleteMovie());


        movieButtonPanel.add(addMovieButton);
        movieButtonPanel.add(editMovieButton);
        movieButtonPanel.add(deleteMovieButton);

        moviePanel.add(movieButtonPanel,BorderLayout.SOUTH);

        tabbedPane.addTab("Movies", moviePanel);

        loadMovies();
    }

    private void loadMovies() {
        movieTableModel.setRowCount(0); // 清空表格
        List<Movie> movies = adminService.getAllMovies();
        for (Movie movie : movies) {
            movieTableModel.addRow(new Object[]{movie.getId(), movie.getTitle(), movie.getDirector(), movie.getGenre(), movie.getDuration()});
        }
    }


    private void showAddMovieDialog() {
        JDialog dialog = new JDialog(this, "Add New Movie", true);
        dialog.setLayout(new GridLayout(6, 2));

        JLabel titleLabel = new JLabel("Title:");
        JTextField titleField = new JTextField(20);

        JLabel directorLabel = new JLabel("Director:");
        JTextField directorField = new JTextField(20);

        JLabel genreLabel = new JLabel("Genre:");
        JTextField genreField = new JTextField(20);


        JLabel durationLabel = new JLabel("Duration (minutes):");
        JTextField durationField = new JTextField(20);

        JButton addButton = new JButton("Add");
        addButton.addActionListener(e -> {
            String title = titleField.getText();
            String director = directorField.getText();
            String genre = genreField.getText();
            String durationText = durationField.getText();
            if(title.isEmpty() || director.isEmpty() || genre.isEmpty() || durationText.isEmpty()){
                JOptionPane.showMessageDialog(dialog,"Please fill in all the blanks");
                return;
            }
            try{
                int duration = Integer.parseInt(durationText);
                String id = UUID.randomUUID().toString();
                Movie movie = new Movie(id,title,director,genre,duration);
                adminService.addMovie(movie);
                loadMovies();
                dialog.dispose();
            }catch (NumberFormatException exception){
                JOptionPane.showMessageDialog(dialog,"Please input a valid number");
            }

        });

        dialog.add(titleLabel);
        dialog.add(titleField);
        dialog.add(directorLabel);
        dialog.add(directorField);
        dialog.add(genreLabel);
        dialog.add(genreField);
        dialog.add(durationLabel);
        dialog.add(durationField);
        dialog.add(new JLabel());
        dialog.add(addButton);

        dialog.setSize(400, 300);
        dialog.setLocationRelativeTo(this);
        dialog.setVisible(true);
    }


    private void showEditMovieDialog() {
        int selectedRow = movieTable.getSelectedRow();
        if(selectedRow == -1){
            JOptionPane.showMessageDialog(this,"Please Select a movie to Edit");
            return;
        }

        String movieId = (String) movieTableModel.getValueAt(selectedRow,0);
        Movie movie = adminService.getAllMovies().stream().filter(e->e.getId().equals(movieId)).findFirst().orElse(null);

        JDialog dialog = new JDialog(this, "Edit Movie", true);
        dialog.setLayout(new GridLayout(6, 2));

        JLabel titleLabel = new JLabel("Title:");
        JTextField titleField = new JTextField(movie.getTitle(),20);

        JLabel directorLabel = new JLabel("Director:");
        JTextField directorField = new JTextField(movie.getDirector(),20);

        JLabel genreLabel = new JLabel("Genre:");
        JTextField genreField = new JTextField(movie.getGenre(),20);


        JLabel durationLabel = new JLabel("Duration (minutes):");
        JTextField durationField = new JTextField(String.valueOf(movie.getDuration()),20);

        JButton editButton = new JButton("Edit");
        editButton.addActionListener(e -> {
            String title = titleField.getText();
            String director = directorField.getText();
            String genre = genreField.getText();
            String durationText = durationField.getText();
            if(title.isEmpty() || director.isEmpty() || genre.isEmpty() || durationText.isEmpty()){
                JOptionPane.showMessageDialog(dialog,"Please fill in all the blanks");
                return;
            }
            try{
                int duration = Integer.parseInt(durationText);
                Movie updatedMovie = new Movie(movieId,title,director,genre,duration);
                adminService.updateMovie(updatedMovie);
                loadMovies();
                dialog.dispose();
            }catch (NumberFormatException exception){
                JOptionPane.showMessageDialog(dialog,"Please input a valid number");
            }

        });

        dialog.add(titleLabel);
        dialog.add(titleField);
        dialog.add(directorLabel);
        dialog.add(directorField);
        dialog.add(genreLabel);
        dialog.add(genreField);
        dialog.add(durationLabel);
        dialog.add(durationField);
        dialog.add(new JLabel());
        dialog.add(editButton);

        dialog.setSize(400, 300);
        dialog.setLocationRelativeTo(this);
        dialog.setVisible(true);
    }

    private void deleteMovie(){
        int selectedRow = movieTable.getSelectedRow();
        if(selectedRow == -1){
            JOptionPane.showMessageDialog(this,"Please Select a movie to Delete");
            return;
        }
        String movieId = (String) movieTableModel.getValueAt(selectedRow,0);
        adminService.deleteMovie(movieId);
        loadMovies();
    }


    private void createScreeningTab() {
        JPanel screeningPanel = new JPanel(new BorderLayout());
        screeningTableModel = new DefaultTableModel(new Object[]{"ID", "Movie ID","Start Time", "Price", "Available Seats"}, 0);
        screeningTable = new JTable(screeningTableModel);
        JScrollPane screeningScrollPane = new JScrollPane(screeningTable);
        screeningPanel.add(screeningScrollPane, BorderLayout.CENTER);

        JPanel screeningButtonPanel = new JPanel();
        JButton addScreeningButton = new JButton("Add Screening");
        addScreeningButton.addActionListener(e -> showAddScreeningDialog());

        JButton editScreeningButton = new JButton("Edit Screening");
        editScreeningButton.addActionListener(e -> showEditScreeningDialog());

        JButton deleteScreeningButton = new JButton("Delete Screening");
        deleteScreeningButton.addActionListener(e -> deleteScreening());


        screeningButtonPanel.add(addScreeningButton);
        screeningButtonPanel.add(editScreeningButton);
        screeningButtonPanel.add(deleteScreeningButton);

        screeningPanel.add(screeningButtonPanel,BorderLayout.SOUTH);


        tabbedPane.addTab("Screenings", screeningPanel);

        loadScreenings();
    }

    private void loadScreenings() {
        screeningTableModel.setRowCount(0); // 清空表格
        List<Screening> screenings = adminService.getAllScreenings();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");

        for (Screening screening : screenings) {
            screeningTableModel.addRow(new Object[]{screening.getId(), screening.getMovieId(), screening.getStartTime().format(formatter),
                    screening.getPrice(), screening.getSeatsAvailable()});
        }
    }

    private void showAddScreeningDialog() {
        JDialog dialog = new JDialog(this, "Add New Screening", true);
        dialog.setLayout(new GridLayout(6, 2));

        JLabel movieIdLabel = new JLabel("Movie ID:");
        JTextField movieIdField = new JTextField(20);

        JLabel startTimeLabel = new JLabel("Start Time (yyyy-MM-dd HH:mm):");
        JTextField startTimeField = new JTextField(20);

        JLabel priceLabel = new JLabel("Price:");
        JTextField priceField = new JTextField(20);

        JLabel seatsAvailableLabel = new JLabel("Available Seats:");
        JTextField seatsAvailableField = new JTextField(20);


        JButton addButton = new JButton("Add");
        addButton.addActionListener(e -> {
            String movieId = movieIdField.getText();
            String startTimeText = startTimeField.getText();
            String priceText = priceField.getText();
            String seatsAvailableText = seatsAvailableField.getText();

            if(movieId.isEmpty() || startTimeText.isEmpty() || priceText.isEmpty() || seatsAvailableText.isEmpty()){
                JOptionPane.showMessageDialog(dialog,"Please fill in all the blanks");
                return;
            }
            try{
                LocalDateTime startTime = LocalDateTime.parse(startTimeText, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
                double price = Double.parseDouble(priceText);
                int seatsAvailable = Integer.parseInt(seatsAvailableText);
                String id = UUID.randomUUID().toString();
                Screening screening = new Screening(id,movieId,startTime,price,seatsAvailable);
                adminService.addScreening(screening);
                loadScreenings();
                dialog.dispose();
            }catch (Exception exception){
                 JOptionPane.showMessageDialog(dialog,"Please input a valid info");
            }

        });

        dialog.add(movieIdLabel);
        dialog.add(movieIdField);
        dialog.add(startTimeLabel);
        dialog.add(startTimeField);
        dialog.add(priceLabel);
        dialog.add(priceField);
        dialog.add(seatsAvailableLabel);
        dialog.add(seatsAvailableField);
        dialog.add(new JLabel());
        dialog.add(addButton);


        dialog.setSize(400, 300);
        dialog.setLocationRelativeTo(this);
        dialog.setVisible(true);
    }

    private void showEditScreeningDialog() {

        int selectedRow = screeningTable.getSelectedRow();
        if(selectedRow == -1){
            JOptionPane.showMessageDialog(this,"Please Select a Screening to Edit");
            return;
        }

        String screeningId = (String) screeningTableModel.getValueAt(selectedRow,0);
        Screening screening = adminService.getAllScreenings().stream().filter(e->e.getId().equals(screeningId)).findFirst().orElse(null);

        JDialog dialog = new JDialog(this, "Edit Screening", true);
        dialog.setLayout(new GridLayout(6, 2));

        JLabel movieIdLabel = new JLabel("Movie ID:");
        JTextField movieIdField = new JTextField(screening.getMovieId(),20);

        JLabel startTimeLabel = new JLabel("Start Time (yyyy-MM-dd HH:mm):");
        JTextField startTimeField = new JTextField(screening.getStartTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")),20);

        JLabel priceLabel = new JLabel("Price:");
        JTextField priceField = new JTextField(String.valueOf(screening.getPrice()),20);

        JLabel seatsAvailableLabel = new JLabel("Available Seats:");
        JTextField seatsAvailableField = new JTextField(String.valueOf(screening.getSeatsAvailable()),20);


        JButton editButton = new JButton("Edit");
        editButton.addActionListener(e -> {
            String movieId = movieIdField.getText();
            String startTimeText = startTimeField.getText();
            String priceText = priceField.getText();
            String seatsAvailableText = seatsAvailableField.getText();

            if(movieId.isEmpty() || startTimeText.isEmpty() || priceText.isEmpty() || seatsAvailableText.isEmpty()){
                JOptionPane.showMessageDialog(dialog,"Please fill in all the blanks");
                return;
            }
            try{
                LocalDateTime startTime = LocalDateTime.parse(startTimeText, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
                double price = Double.parseDouble(priceText);
                int seatsAvailable = Integer.parseInt(seatsAvailableText);
                Screening updatedScreening = new Screening(screeningId,movieId,startTime,price,seatsAvailable);
                adminService.updateScreening(updatedScreening);
                loadScreenings();
                dialog.dispose();
            }catch (Exception exception){
                 JOptionPane.showMessageDialog(dialog,"Please input a valid info");
            }
        });

        dialog.add(movieIdLabel);
        dialog.add(movieIdField);
        dialog.add(startTimeLabel);
        dialog.add(startTimeField);
        dialog.add(priceLabel);
        dialog.add(priceField);
        dialog.add(seatsAvailableLabel);
        dialog.add(seatsAvailableField);
        dialog.add(new JLabel());
        dialog.add(editButton);


        dialog.setSize(400, 300);
        dialog.setLocationRelativeTo(this);
        dialog.setVisible(true);
    }


    private void deleteScreening(){
        int selectedRow = screeningTable.getSelectedRow();
        if(selectedRow == -1){
            JOptionPane.showMessageDialog(this,"Please Select a Screening to Delete");
            return;
        }
        String screeningId = (String) screeningTableModel.getValueAt(selectedRow,0);
        adminService.deleteScreening(screeningId);
        loadScreenings();
    }
}
